﻿#pragma once

#include "AMain.h"
#include "Launcher.Config.h"
#include <string>
#include <vector>
#include <deque>
#include <stdexcept>
#include <any>
#include "exceptionhelper.h"
#include "../../stringhelper.h"
#include "../../tangible_filesystem.h"

using namespace Client;


namespace Launcher
{
    class AMain : public System::Windows::Forms::Form
    {
    private:
        long long _totalBytes = 0, _completedBytes = 0, _currentBytes = 0;
        int _fileCount = 0, _currentCount = 0;

        FileInformation *_currentFile;
    public:
        bool Completed = false, Checked = false, CleanFiles = false, LabelSwitch = false, ErrorFound = false;

        std::vector<FileInformation*> OldList;
        std::deque<FileInformation*> DownloadList;

    private:
        Stopwatch *_stopwatch = Stopwatch::StartNew();

    public:
        Thread *_workThread;

    private:
        bool dragging = false;
        Point *dragCursorPoint;
        Point *dragFormPoint;

        Config *ConfigForm = new Config();

        bool Restart = false;

    public:
        virtual ~AMain()
        {
            delete _currentFile;
            delete _stopwatch;
            delete _workThread;
            delete dragCursorPoint;
            delete dragFormPoint;
            delete ConfigForm;
            delete components;
            delete ActionLabel;
            delete SpeedLabel;
            delete InterfaceTimer;
            delete Launch_pb;
            delete Close_pb;
            delete Movement_panel;
            delete TotalProg_pb;
            delete ProgressCurrent_pb;
            delete Main_browser;
            delete Name_label;
            delete ProgEnd_pb;
            delete ProgTotalEnd_pb;
            delete CurrentFile_label;
            delete CurrentPercent_label;
            delete TotalPercent_label;
            delete Credit_label;
            delete Version_label;
            delete Config_pb;
            delete pictureBox1;
        }

        AMain();

        static void SaveError(const std::string &ex);

        void Start();



    private:
        void BeginDownload();
        void CleanUp();
    public:
        bool NeedFile(const std::string &fileName);


        void ParseOld(BinaryReader *reader);

        void CheckFile(FileInformation *old);

        void Download(FileInformation *info);

        std::vector<unsigned char> Download(const std::string &fileName);
        static std::vector<unsigned char> Decompress(std::vector<unsigned char> &raw);
        static std::vector<unsigned char> Compress(std::vector<unsigned char> &raw);

        FileInformation *GetFileInformation(const std::string &fileName);

    private:
        void AMain_Load(std::any sender, EventArgs *e);

        void Launch_pb_Click(std::any sender, EventArgs *e);

        void Launch();

        void Close_pb_Click(std::any sender, EventArgs *e);

        void Movement_panel_MouseClick(std::any sender, MouseEventArgs *e);

        void Movement_panel_MouseUp(std::any sender, MouseEventArgs *e);

        void Movement_panel_MouseMove(std::any sender, MouseEventArgs *e);

        void Launch_pb_MouseEnter(std::any sender, EventArgs *e);

        void Launch_pb_MouseLeave(std::any sender, EventArgs *e);

        void Close_pb_MouseEnter(std::any sender, EventArgs *e);

        void Close_pb_MouseLeave(std::any sender, EventArgs *e);

        void Launch_pb_MouseDown(std::any sender, MouseEventArgs *e);

        void Launch_pb_MouseUp(std::any sender, MouseEventArgs *e);

        void Close_pb_MouseDown(std::any sender, MouseEventArgs *e);

        void Close_pb_MouseUp(std::any sender, MouseEventArgs *e);

        void ProgressCurrent_pb_SizeChanged(std::any sender, EventArgs *e);

        void Config_pb_MouseDown(std::any sender, MouseEventArgs *e);

        void Config_pb_MouseEnter(std::any sender, EventArgs *e);

        void Config_pb_MouseLeave(std::any sender, EventArgs *e);

        void Config_pb_MouseUp(std::any sender, MouseEventArgs *e);

        void Config_pb_Click(std::any sender, EventArgs *e);

        void TotalProg_pb_SizeChanged(std::any sender, EventArgs *e);

        void Main_browser_DocumentCompleted(std::any sender, WebBrowserDocumentCompletedEventArgs *e);

        void InterfaceTimer_Tick(std::any sender, EventArgs *e);

        void AMain_Click(std::any sender, EventArgs *e);

        void ActionLabel_Click(std::any sender, EventArgs *e);

        void Credit_label_Click(std::any sender, EventArgs *e);

        void AMain_FormClosed(std::any sender, FormClosedEventArgs *e);

        void RepairOldFiles();

        void MoveOldFilesToCurrent();


        /// <summary>
        /// Required designer variable.
        /// </summary>
        System::ComponentModel::IContainer *components = nullptr;


        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected:
        void Dispose(bool disposing) override;

        #pragma region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
    private:
        void InitializeComponent();

        #pragma endregion
        System::Windows::Forms::Label *ActionLabel;
        System::Windows::Forms::Label *SpeedLabel;
    public:
        System::Windows::Forms::Timer *InterfaceTimer;
        System::Windows::Forms::PictureBox *Launch_pb;
    private:
        System::Windows::Forms::PictureBox *Close_pb;
        System::Windows::Forms::Panel *Movement_panel;
        System::Windows::Forms::PictureBox *TotalProg_pb;
        System::Windows::Forms::PictureBox *ProgressCurrent_pb;
        System::Windows::Forms::WebBrowser *Main_browser;
        System::Windows::Forms::Label *Name_label;
        System::Windows::Forms::PictureBox *ProgEnd_pb;
        System::Windows::Forms::PictureBox *ProgTotalEnd_pb;
        System::Windows::Forms::Label *CurrentFile_label;
        System::Windows::Forms::Label *CurrentPercent_label;
        System::Windows::Forms::Label *TotalPercent_label;
        System::Windows::Forms::Label *Credit_label;
        System::Windows::Forms::Label *Version_label;
        System::Windows::Forms::PictureBox *Config_pb;
        System::Windows::Forms::PictureBox *pictureBox1;
    };
}
